package com.yisu.auction.api.web.interceptor;


import com.google.common.collect.Maps;
import com.yisu.auction.api.core.service.IMemberService;
import com.yisu.auction.api.domain.config.SystemConfig;
import com.yisu.auction.ewf.common.enums.LoginTypeEnum;
import com.yisu.auction.ewf.common.enums.ResponseCode;
import com.yisu.auction.ewf.common.web.JsonResult;
import com.yisu.auction.ewf.entity.UserToken;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Enumeration;
import java.util.Map;


/**
 * 切面拦截器
 * 接口验证，此拦截器对所有接口进行登录类型判断，签名验证-未实现等操作
 * Created by zj on 2017/3/16.
 */
@Component
@Aspect
public class AuthVerifyAspect {
    @Resource
    private SystemConfig systemConfig;
    @Resource
    private IMemberService iMemberService;
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 拦截所有IAuthVerifyAnnotation注解方法
     */
    @Pointcut("execution(@com.yisu.auction.api.web.interceptor.IAuthVerifyAnnotation * *(..))")
    public void controllerPointcut() {
    }

    @Around("controllerPointcut()")
    public Object controllerAround(ProceedingJoinPoint joinPoint) {
        try {
            String className = joinPoint.getTarget().getClass().getSimpleName();
            Object[] args = joinPoint.getArgs();
            String methodName = joinPoint.getSignature().getName();
            Class<?> classTarget = joinPoint.getTarget().getClass();
            Class<?>[] par = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
            Method objMethod = classTarget.getMethod(methodName, par);
            IAuthVerifyAnnotation authVerifyAnnotation = objMethod.getAnnotation(IAuthVerifyAnnotation.class);
            Map paramMap = getUrlParam(joinPoint);
            if (paramMap != null) {
                LoginTypeEnum loginTypeEnum = authVerifyAnnotation.LoginTypeEnum();
                if (loginTypeEnum.code == LoginTypeEnum.NEED_LOGIN.code) {
                    String userToken = String.valueOf(paramMap.get("userToken"));
                    if (StringUtils.isEmpty(userToken)) {
                        return new JsonResult(ResponseCode.TOKEN_NOT_EXIST.code, "请登录！");
                    } else {
                        UserToken token = iMemberService.getUserTokenByToken(userToken);
                        if (token == null) {
                            return new JsonResult(ResponseCode.TOKEN_NOT_EXIST.code, "请登录！");
                        } else {
                            if (token.getExpirationTime().getTime() - (new Date()).getTime() < 0) {
                                return new JsonResult(ResponseCode.TOKEN_NOT_EXIST.code, "请登录！");
                            }
                        }
                    }
                }
            }
            return joinPoint.proceed();
        } catch (Exception e) {
            logger.error("IAuthVerifyAnnotation权限验证注解拦截失败，异常信息：" + e.getMessage(), e);
        } catch (Throwable throwable) {
            logger.error("IAuthVerifyAnnotation权限验证注解拦截失败，异常信息：" + throwable.getMessage(), throwable);
        }
        return null;
    }

    /**
     * 获取URL参数
     *
     * @return
     */
    protected Map<String, String> getUrlParam(ProceedingJoinPoint joinPoint) {
        Map<String, String> urlParam = Maps.newConcurrentMap();
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        Enumeration nameEn = request.getParameterNames();
        while (nameEn.hasMoreElements()) {
            String paramName = (String) nameEn.nextElement();
            String paramValue = request.getParameter(paramName);
            //形成键值对应的map
            urlParam.put(paramName, paramValue);
        }
        return urlParam;
        /*String url = request.getRequestURL().toString();
        String method = request.getMethod();
        String uri = request.getRequestURI();
        String queryString = request.getQueryString();*/


        /*// 获取接口的请求参数
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        for (int i = 0; i < signature.getParameterNames().length; i++) {
            urlPatam.put(signature.getParameterNames()[i].toLowerCase(), joinPoint.getArgs()[i] + "");
        }
        return urlPatam;*/
    }
}
